﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;
using System.Xml;

namespace Winwise.SPWebConfig.Core
{
    [System.Runtime.InteropServices.GuidAttribute("D14CD923-487E-4721-A907-7A4670B39197")]
    public class WebConfigFileChanges : SPPersistedObject
    {
         // Fields
        [Persisted]
        private List<WebConfigModification> _WebModif;

        [Persisted]
        private List<LogEntry> _Errors;

        [Persisted]
        private List<LogEntry> _Logs;

        public WebConfigFileChanges()
        {
        }
        public WebConfigFileChanges(string name, SPPersistedObject parent)
            : base(name, parent)
        {
            
        }


        protected override void Validate()
        {
            base.Validate();
            List<WebConfigModification> toDelete = new List<WebConfigModification>();
            string message = "";
            foreach (var item in WebModif)
            {
                try
                {
                    item.Validate();
                }
                catch (Exception e)
                {
                    message += e.ToString() + Environment.NewLine;
                    toDelete.Add(item);
                }
            }
            foreach (var item in toDelete)
            {
                WebModif.Remove(item);
            }
            if (!string.IsNullOrEmpty(message))
            {
                throw new Exception(message);
            }

        }

        public List<LogEntry> Errors
        {
            get
            {
                if (_Errors == null)
                {
                    _Errors = new List<LogEntry>();
                }
                return _Errors;
            }
        }



        public List<LogEntry> Logs
        {
            get
            {
                if (_Logs == null)
                {
                    _Logs = new List<LogEntry>();
                }
                return _Logs;
            }
        }

        internal void LogError(string message)
        {
            Errors.Add(new LogEntry() { DateTime = DateTime.Now.ToString("o"), Message = message });
            LoggingService.LogError("CustomWebConfig", message);
        }


        public List<WebConfigModification> WebModif
        {
            get
            {
                if (_WebModif == null)
                {
                    _WebModif = new List<WebConfigModification>();
                }
                return _WebModif;
            }
            set
            {
                _WebModif = value;
            }
        }


        private IEnumerable<WebConfigModification> GetWebModifByZone(SPUrlZone zone)
        {
            IEnumerable<WebConfigModification> webmodifs = from w in WebModif where w.Zones.Contains(zone) select w;
            return webmodifs;
        }

        public static string GenerateNameByServerAndZone(Guid serverID, SPUrlZone zone)
        {
            return String.Format("WebConfigModification-Server-{0}-zone-{1}", serverID.ToString(), zone.ToString());
        }

        internal static string GenerateName()
        {
            return String.Format("WebConfigModification");
        }

        internal void RemoveModifications(XmlDocument doc, SPUrlZone zone, SPWebApplication webapp, List<Guid>ExcludedModifs, Guid OnlyWebModif)
        {
            ApplyOperations(doc, zone, webapp, ExcludedModifs, OnlyWebModif, false);
        }

        internal void ApplyModifications(XmlDocument doc, SPUrlZone zone, SPWebApplication webapp, List<Guid> ExcludedModifs, Guid OnlyWebModif)
        {
            ApplyOperations(doc, zone, webapp, ExcludedModifs, OnlyWebModif, true);
        }

        private void ApplyOperations(XmlDocument doc, SPUrlZone zone, SPWebApplication webapp, List<Guid> ExcludedModifs, Guid OnlyWebModif, bool add)
        {
            foreach (WebConfigModification webModif in GetWebModifByZone(zone))
            {
                if (OnlyWebModif != Guid.Empty)
                {
                    if (webModif.ID != OnlyWebModif)
                    {
                        continue;
                    }
                }
                if (ExcludedModifs != null && ExcludedModifs.Contains(webModif.ID))
                {
                    continue;
                }
                try
                {
                    webModif.LastOperationMessage = "";
                    string message = "";
                    if (add)
                    {
                        webModif.ApplyModification(doc, zone, webapp);
                        message = string.Format("Applyed modification {0}", webModif.DisplayName);
                    }
                    else
                    {
                        webModif.RemoveModification(doc, zone, webapp);
                        message = string.Format("UnApplyed modification {0}", webModif.DisplayName);
                    }
                    if (webModif.LastOperationMessage != "")
                    {
                        Logs.Add(new LogEntry()
                        {
                            DateTime = DateTime.Now.ToString("o"),
                            Message = webModif.LastOperationMessage
                        });
                        webModif.LastOperationMessage = "";
                    }

                    Logs.Add(new LogEntry()
                    {
                        DateTime = DateTime.Now.ToString("o"),
                        Message = message
                    });
                }
                catch (Exception e)
                {

                    LogError(e.ToString());
                    continue;

                }
            }
        }


    }
}
